package cn.com.xf.task;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.ibatis.SqlMapClientTemplate;
import org.springframework.stereotype.Service;

import cn.com.xf.dao.TblCheckDataDAO;
import cn.com.xf.dao.TblCheckHolidayDAO;
import cn.com.xf.dao.TblCheckLeaveDAO;
import cn.com.xf.dao.TblCheckMendDAO;
import cn.com.xf.dao.TblCheckReportDAO;
import cn.com.xf.dao.TblCheckScheduleDAO;
import cn.com.xf.dao.TblCheckShiftDAO;
import cn.com.xf.dao.TsUserDAO;
import cn.com.xf.dao.impl.TblCheckDataDAOImpl;
import cn.com.xf.dao.impl.TblCheckHolidayDAOImpl;
import cn.com.xf.dao.impl.TblCheckLeaveDAOImpl;
import cn.com.xf.dao.impl.TblCheckMendDAOImpl;
import cn.com.xf.dao.impl.TblCheckReportDAOImpl;
import cn.com.xf.dao.impl.TblCheckScheduleDAOImpl;
import cn.com.xf.dao.impl.TblCheckShiftDAOImpl;
import cn.com.xf.domain.TblCheckData;
import cn.com.xf.domain.TblCheckHoliday;
import cn.com.xf.domain.TblCheckLeave;
import cn.com.xf.domain.TblCheckMend;
import cn.com.xf.domain.TblCheckReport;
import cn.com.xf.domain.TblCheckSchedule;
import cn.com.xf.domain.TblCheckShift;
import cn.com.xf.utils.DateUtils;

@Service
public class AnalyzeTask implements Runnable {
	@Autowired
	private TblCheckScheduleDAOImpl scheduleDAO;
	private TblCheckShiftDAOImpl shiftDAO;
	private TblCheckMendDAOImpl mendDAO;
	private TblCheckLeaveDAOImpl leaveDAO;
	private TblCheckDataDAOImpl checkDataDAO;
	private TblCheckHolidayDAOImpl holidayDAO;
	private TblCheckReportDAOImpl reportDAO;
	
	String userid;
	Date startDate;
	Date endDate;
	
	public AnalyzeTask(String userid, Date startDate, Date endDate) {
		this.userid = userid;
		this.startDate = startDate;
		this.endDate = endDate;
		scheduleDAO = new TblCheckScheduleDAOImpl();
		scheduleDAO.setSqlMapClientTemplate(SqlMapClientTemplateManager.getConnection());
		shiftDAO = new TblCheckShiftDAOImpl();
		shiftDAO.setSqlMapClientTemplate(SqlMapClientTemplateManager.getConnection());
		mendDAO = new TblCheckMendDAOImpl();
		mendDAO.setSqlMapClientTemplate(SqlMapClientTemplateManager.getConnection());
		leaveDAO = new TblCheckLeaveDAOImpl();
		leaveDAO.setSqlMapClientTemplate(SqlMapClientTemplateManager.getConnection());
		checkDataDAO = new TblCheckDataDAOImpl();
		checkDataDAO.setSqlMapClientTemplate(SqlMapClientTemplateManager.getConnection());
		holidayDAO = new TblCheckHolidayDAOImpl();
		holidayDAO.setSqlMapClientTemplate(SqlMapClientTemplateManager.getConnection());
		reportDAO = new TblCheckReportDAOImpl();
		reportDAO.setSqlMapClientTemplate(SqlMapClientTemplateManager.getConnection());
	}



	@Override
	public void run() {
		try {
			//System.out.println("----------------------analyze=============");
			List<TblCheckSchedule> scheduleList = scheduleDAO.selectScheduleByUserid(userid);
			Calendar calendar = Calendar.getInstance();
			Date curDate = startDate;
			// 遍历日期范围
			while (curDate.compareTo(endDate) <= 0) {
				double shouldHours = 0;
				double realHours = 0;
				double offworkHours = 0;
				double leaveHours = 0;
				int latenum = 0; //迟到次数
				int earlynum = 0; //早退次数
				double offworknum = 0; //旷工天数
				double leavenum = 0;
				double holidaynum = 0;
				long fLateMin = 0;
				long sLateMin = 0;
				long tLateMin = 0;
				long fEarlyMin = 0;
				long sEarlyMin = 0;
				long tEarlyMin = 0;
				Date fCheckin = null;
				Date sCheckin = null;
				Date tCheckin = null;
				Date fCheckout = null;
				Date sCheckout = null;
				Date tCheckout = null;
				calendar.setTime(curDate);
				boolean isScheduled = false;
				String day = calendar.get(Calendar.DAY_OF_WEEK) - 1 + "";
				// 查询当天补卡信息
				List<TblCheckMend> mendList = mendDAO.selectMendByUseridAndCheckdate(userid, curDate);
				// 查询当天考勤数据
				List<TblCheckData> checkDataList = checkDataDAO.selectCheckDataByUseridAndDate(userid, curDate);							
				// 查询员工请假
				List<TblCheckLeave> leaveList = leaveDAO.selectLeaveByUserid(userid);
				List<TblCheckHoliday> holidayList = holidayDAO.selectBySiteid(userid.substring(0, 6));
				// 把补卡信息加入到考勤数据列表
				if (mendList.size() > 0) {
					for (TblCheckMend mend: mendList) {
						// 上班卡
						if (mend.getType() == 0) {
							if (mend.getTime1() != null) {
								TblCheckData checkData = new TblCheckData();
								checkData.setCheckdate(curDate);
								checkData.setChecktime(mend.getTime1());
								checkData.setType((short) 0);
								checkDataList.add(checkData);
							}
							if (mend.getTime2() != null) {
								TblCheckData checkData = new TblCheckData();
								checkData.setCheckdate(curDate);
								checkData.setChecktime(mend.getTime2());
								checkData.setType((short) 0);
								checkDataList.add(checkData);
							}	
							if (mend.getTime3() != null) {
								TblCheckData checkData = new TblCheckData();
								checkData.setCheckdate(curDate);
								checkData.setChecktime(mend.getTime3());
								checkData.setType((short) 0);
								checkDataList.add(checkData);
							}							
						}
						// 下班卡
						if (mend.getType() == 1) {
							if (mend.getTime1() != null) {
								TblCheckData checkData = new TblCheckData();
								checkData.setCheckdate(curDate);
								checkData.setChecktime(mend.getTime1());
								checkData.setType((short) 1);
								checkDataList.add(checkData);
							}
							if (mend.getTime2() != null) {
								TblCheckData checkData = new TblCheckData();
								checkData.setCheckdate(curDate);
								checkData.setChecktime(mend.getTime2());
								checkData.setType((short) 1);
								checkDataList.add(checkData);
							}	
							if (mend.getTime3() != null) {
								TblCheckData checkData = new TblCheckData();
								checkData.setCheckdate(curDate);
								checkData.setChecktime(mend.getTime3());
								checkData.setType((short) 1);
								checkDataList.add(checkData);
							}							
						}							
					}
				}	
				for (TblCheckSchedule schedule : scheduleList) {
					// 判断当前日期在排班日期范围内
					if (schedule.getStartdate().compareTo(curDate) <= 0
							&& schedule.getEnddate().compareTo(curDate) >= 0) {
						isScheduled = true;
						// 查询班次信息
						TblCheckShift shift = shiftDAO.selectShiftById(schedule.getShiftid());
						// 当天的班次签到签退时间
						Date fCheckintime=null,fCheckouttime=null,sCheckintime=null,sCheckouttime=null,tCheckintime=null,tCheckouttime=null;
						if (shift.getfCheckintime()!=null&&!shift.getfCheckintime().equals(":"))
							fCheckintime = DateUtils.connectDateAndTime(curDate, shift.getfCheckintime());
						if (shift.getfCheckouttime()!=null&&!shift.getfCheckouttime().equals(":"))
							fCheckouttime = DateUtils.connectDateAndTime(curDate, shift.getfCheckouttime());
						if (shift.getsCheckintime()!=null&&!shift.getsCheckintime().equals(":"))
							sCheckintime = DateUtils.connectDateAndTime(curDate, shift.getsCheckintime());
						if (shift.getsCheckouttime()!=null&&!shift.getsCheckouttime().equals(":"))
							sCheckouttime = DateUtils.connectDateAndTime(curDate, shift.getsCheckouttime());
						if (shift.gettCheckintime()!=null&&!shift.gettCheckintime().equals(":"))
							tCheckintime = DateUtils.connectDateAndTime(curDate, shift.gettCheckintime());
						if (shift.gettCheckouttime()!=null&&!shift.gettCheckouttime().equals(":"))
							tCheckouttime = DateUtils.connectDateAndTime(curDate, shift.gettCheckouttime());					
						// 第一个时间段计算迟到，而且是工作日
						if (shift.getfAsLate()!=null && shift.getfAsLate().trim().equals("1")) {
							boolean hasData = false;
							boolean isLeave = false;
							boolean isHoliday = false;
							for (TblCheckLeave leave: leaveList) {
								if (leave.getStartdate().compareTo(fCheckintime) <= 0 && leave.getEnddate().compareTo(fCheckintime) >= 0) {
									isLeave = true;
								}
							}
							for (TblCheckHoliday holiday: holidayList) {
								if (holiday.getStartdate().compareTo(fCheckintime) <= 0 && holiday.getEnddate().compareTo(fCheckintime) >= 0) {
									isHoliday = true;
								}
							}
							if (!isHoliday && shift.getfWorkDay().contains(day)) {
								shouldHours = shouldHours + DateUtils.getHour(fCheckintime, fCheckouttime);
								List<Date> allChecktime = new ArrayList<Date>();
								for (TblCheckData checkData: checkDataList) {
									if (checkData.getType() == 0) {
										if (checkData.getChecktime().compareTo(fCheckouttime) < 0) {
											hasData =  true;
											allChecktime.add(checkData.getChecktime());
											
										} 
									}
								}
	
								if (!hasData) {
									// 旷工
									if (!isLeave) {
										offworknum = offworknum + Double.parseDouble(shift.getfCheckedDays());
										offworkHours += DateUtils.getHour(fCheckintime, fCheckouttime);
									} else {
										leavenum = leavenum + Double.parseDouble(shift.getfCheckedDays());
										leaveHours = leaveHours + DateUtils.getHour(fCheckintime, fCheckouttime);									
									}
								} else {
									fCheckin = DateUtils.getFirstDate(allChecktime);
									Calendar ca = Calendar.getInstance();
									ca.setTime(fCheckintime);
									// 当天班次上班时间加上设置的迟到分钟数
									ca.add(Calendar.MINUTE, shift.getfLaterMinute());
									if (fCheckin.compareTo(ca.getTime()) > 0) {
										//迟到
										latenum++;
										//迟到分钟数
										fLateMin = (fCheckin.getTime() - ca.getTimeInMillis()) / (1000 * 60);
									}								
								}
							} else {
								if (isHoliday)
									holidaynum = holidaynum + Double.parseDouble(shift.getfCheckedDays());
							}
						}
						
						if (shift.getfAsEarly()!=null && shift.getfAsEarly().trim().equals("1")) {
							boolean hasData = false;
							boolean isLeave = false;
							boolean isHoliday = false;
							for (TblCheckLeave leave: leaveList) {
								if (leave.getStartdate().compareTo(fCheckouttime) <= 0 && leave.getEnddate().compareTo(fCheckouttime) >= 0) {
									isLeave = true;
								}
							}
							for (TblCheckHoliday holiday: holidayList) {
								if (holiday.getStartdate().compareTo(fCheckouttime) <= 0 && holiday.getEnddate().compareTo(fCheckouttime) >= 0) {
									isHoliday = true;
								}
							}
							if (!isHoliday && shift.getfWorkDay().contains(day)) {
								List<Date> allChecktime = new ArrayList<Date>();
								for (TblCheckData checkData: checkDataList) {
									if (checkData.getType() == 1) {
										if (checkData.getChecktime().compareTo(sCheckintime) < 0) {
											hasData = true;
											allChecktime.add(checkData.getChecktime());
	
										}
									}
								}
								if (!hasData) {
									if (!isLeave) {
										earlynum++;
									}							
								} else {	
									fCheckout = DateUtils.getLastDate(allChecktime);
									Calendar ca = Calendar.getInstance();
									ca.setTime(fCheckouttime);
									// 当天班次下班时间减去设置的早退分钟数
									ca.add(Calendar.MINUTE, -1*shift.getfEarlierMinute());
									if (fCheckout.compareTo(ca.getTime()) < 0) {
										//早退
										earlynum++;
										fEarlyMin = (ca.getTimeInMillis() - fCheckout.getTime()) / (1000 * 60);
									}
								}
							}
							
						}
						
						if (shift.getsAsLate()!=null && shift.getsAsLate().trim().equals("1")) {
							boolean hasData = false;
							boolean isLeave = false;
							boolean isHoliday = false;
							for (TblCheckLeave leave: leaveList) {
								if (leave.getStartdate().compareTo(sCheckintime) <= 0 && leave.getEnddate().compareTo(sCheckintime) >= 0) {
									isLeave = true;
								}
							}
							for (TblCheckHoliday holiday: holidayList) {
								if (holiday.getStartdate().compareTo(sCheckintime) <= 0 && holiday.getEnddate().compareTo(sCheckintime) >= 0) {
									isHoliday = true;
								}
							}
							if (!isHoliday && shift.getsWorkDay().contains(day)) {
								shouldHours = shouldHours + DateUtils.getHour(sCheckintime, sCheckouttime);
								List<Date> allChecktime = new ArrayList<Date>();
								for (TblCheckData checkData: checkDataList) {
									if (checkData.getType() == 0) {
										if (checkData.getChecktime().compareTo(fCheckouttime) > 0 && checkData.getChecktime().compareTo(sCheckouttime) < 0) {
											hasData = true;
											allChecktime.add(checkData.getChecktime());
									
										} 
									}
								}
								
								if (!hasData) {
									if (!isLeave) {
										// 旷工
										offworknum = offworknum + Double.parseDouble(shift.getsCheckedDays());
										offworkHours += DateUtils.getHour(sCheckintime, sCheckouttime);
									} else {
										leavenum = leavenum + Double.parseDouble(shift.getsCheckedDays());
										leaveHours = leaveHours + DateUtils.getHour(sCheckintime, sCheckouttime);
									}
								} else {						
									sCheckin = DateUtils.getFirstDate(allChecktime);
									Calendar ca = Calendar.getInstance();
									ca.setTime(sCheckintime);
									// 当天班次上班时间加上设置的迟到分钟数
									ca.add(Calendar.MINUTE, shift.getsLaterMinute());
									if (sCheckin.compareTo(ca.getTime()) > 0) {
										//迟到
										latenum++;
										sLateMin = (sCheckin.getTime() - ca.getTimeInMillis()) / (1000 * 60);
									}		
								}
							} else {
								if (isHoliday)
									holidaynum = holidaynum + Double.parseDouble(shift.getsCheckedDays());
							}
						}
						
						if (shift.getsAsEarly()!=null && shift.getsAsEarly().trim().equals("1")) {
							boolean hasData = false;
							boolean isLeave = false;
							boolean isHoliday = false;
							for (TblCheckLeave leave: leaveList) {
								if (leave.getStartdate().compareTo(sCheckouttime) <= 0 && leave.getEnddate().compareTo(sCheckouttime) >= 0) {
									isLeave = true;
								}
							}
							for (TblCheckHoliday holiday: holidayList) {
								if (holiday.getStartdate().compareTo(sCheckouttime) <= 0 && holiday.getEnddate().compareTo(sCheckouttime) >= 0) {
									isHoliday = true;
								}
							}
							if (!isHoliday && shift.getsWorkDay().contains(day)) {
								List<Date> allChecktime = new ArrayList<Date>();
								for (TblCheckData checkData: checkDataList) {
									if (checkData.getType() == 1) {
										if (checkData.getChecktime().compareTo(sCheckintime) > 0) {
											hasData = true;
											allChecktime.add(checkData.getChecktime());
										
										}
									}
								}
								
								if (!hasData) {
									if (!isLeave) {
										earlynum++;
									}							
								} else {
									sCheckout = DateUtils.getLastDate(allChecktime);
									Calendar ca = Calendar.getInstance();
									ca.setTime(sCheckouttime);
									// 当天班次下班时间减去设置的早退分钟数
									ca.add(Calendar.MINUTE, -1*shift.getsEarlierMinute());
									if (sCheckout.compareTo(ca.getTime()) < 0) {
										//早退
										earlynum++;
										sEarlyMin = (ca.getTimeInMillis() - sCheckout.getTime()) / (1000 * 60);
									}	
								}
							}
						}
						
						if (shift.gettAsLate()!=null && shift.gettAsLate().trim().equals("1")) {
							boolean hasData = false;
							boolean isLeave = false;
							boolean isHoliday = false;
							for (TblCheckLeave leave: leaveList) {
								if (leave.getStartdate().compareTo(tCheckintime) <= 0 && leave.getEnddate().compareTo(tCheckintime) >= 0) {
									isLeave = true;
								}
							}
							for (TblCheckHoliday holiday: holidayList) {
								if (holiday.getStartdate().compareTo(tCheckintime) <= 0 && holiday.getEnddate().compareTo(tCheckintime) >= 0) {
									isHoliday = true;
								}
							}
							if (!isHoliday && shift.gettWorkDay().contains(day)) {
								shouldHours = shouldHours + DateUtils.getHour(sCheckintime, sCheckouttime);
								List<Date> allChecktime = new ArrayList<Date>();
								for (TblCheckData checkData: checkDataList) {
									if (checkData.getType() == 0) {
										if (checkData.getChecktime().compareTo(sCheckouttime) > 0 && checkData.getChecktime().compareTo(tCheckouttime) < 0) {
											hasData = true;
											allChecktime.add(checkData.getChecktime());
										
										} 
									}
								}
								if (!hasData) {
									if (!isLeave) {
										// 旷工
										offworknum = offworknum + Double.parseDouble(shift.gettCheckedDays());
										offworkHours += DateUtils.getHour(tCheckintime, tCheckouttime);
									} else {
										leavenum = leavenum + Double.parseDouble(shift.gettCheckedDays());
										leaveHours = leaveHours + DateUtils.getHour(tCheckintime, tCheckouttime);
									}
								} else {
									tCheckin = DateUtils.getFirstDate(allChecktime);
									Calendar ca = Calendar.getInstance();
									ca.setTime(tCheckintime);
									// 当天班次上班时间加上设置的迟到分钟数
									ca.add(Calendar.MINUTE, shift.gettLaterMinute());
									if (tCheckin.compareTo(ca.getTime()) > 0) {
										//迟到
										latenum++;
										tLateMin = (tCheckin.getTime() - ca.getTimeInMillis()) / (1000 * 60);
									}	
								}
							} else {
								if (isHoliday)
									holidaynum = holidaynum + Double.parseDouble(shift.gettCheckedDays());
							}
						}					
						
						if (shift.gettAsEarly()!=null && shift.gettAsEarly().trim().equals("1")) {
							boolean hasData = false;
							boolean isLeave = false;
							boolean isHoliday = false;
							for (TblCheckLeave leave: leaveList) {
								if (leave.getStartdate().compareTo(tCheckouttime) <= 0 && leave.getEnddate().compareTo(tCheckouttime) >= 0) {
									isLeave = true;
								}
							}
							for (TblCheckHoliday holiday: holidayList) {
								if (holiday.getStartdate().compareTo(tCheckouttime) <= 0 && holiday.getEnddate().compareTo(tCheckouttime) >= 0) {
									isHoliday = true;
								}
							}
							if (!isHoliday && shift.gettWorkDay().contains(day)) {
								List<Date> allChecktime = new ArrayList<Date>();
								for (TblCheckData checkData: checkDataList) {
									if (checkData.getType() == 1) {
										if (checkData.getChecktime().compareTo(tCheckintime) > 0) {
											hasData = true;
											allChecktime.add(checkData.getChecktime());
										
										}
									}
								}
								
								if (!hasData) {
									if (!isLeave) {
										earlynum++;
									}							
								} else {
									tCheckout = DateUtils.getLastDate(allChecktime);
									Calendar ca = Calendar.getInstance();
									ca.setTime(tCheckouttime);
									// 当天班次下班时间减去设置的早退分钟数
									ca.add(Calendar.MINUTE, -1*shift.gettEarlierMinute());
									if (tCheckout.compareTo(ca.getTime()) < 0) {
										//早退
										earlynum++;
										tEarlyMin = (ca.getTimeInMillis() - tCheckout.getTime()) / (1000 * 60);
									}	
								}
							}
						}					
						
						
					} else {
						// 当前日期不在排班表
						isScheduled = false;
					}
				}
				if (isScheduled) {
					// 计算实际出勤小时数
					long allLateMin = fLateMin + sLateMin + tLateMin;
					long allEarlyMin = fEarlyMin + sEarlyMin + tEarlyMin;
					realHours = shouldHours - allLateMin / 60.0 - allEarlyMin / 60.0 - offworkHours - leaveHours;
					TblCheckReport report = reportDAO.selectByUseridAndCheckdate(userid, curDate);
					if (report != null) {
						report.setShouldHours(shouldHours);
						report.setRealHours(realHours);
						report.setEarlynum(earlynum);
						report.setHolidaynum(holidaynum);
						report.setLatenum(latenum);
						report.setLeavenum(leavenum);
						report.setOffworknum(offworknum);
						report.setfLateMin(fLateMin);
						report.setsLateMin(sLateMin);
						report.settLateMin(tLateMin);
						report.setfEarlyMin(fEarlyMin);
						report.setsEarlyMin(sEarlyMin);
						report.settEarlyMin(tEarlyMin);
						report.setfCheckintime(fCheckin);
						report.setsCheckintime(sCheckin);
						report.settCheckintime(tCheckin);
						report.setfCheckouttime(fCheckout);
						report.setsCheckouttime(sCheckout);
						report.settCheckouttime(tCheckout);
						report.setSiteid(userid.substring(0, 6));
						reportDAO.updateByPrimaryKey(report);
					} else {
						report = new TblCheckReport();
						report.setUserid(userid);
						report.setCheckdate(curDate);
						report.setShouldHours(shouldHours);
						report.setRealHours(realHours);
						report.setEarlynum(earlynum);
						report.setHolidaynum(holidaynum);
						report.setLatenum(latenum);
						report.setLeavenum(leavenum);
						report.setOffworknum(offworknum);
						report.setfLateMin(fLateMin);
						report.setsLateMin(sLateMin);
						report.settLateMin(tLateMin);
						report.setfEarlyMin(fEarlyMin);
						report.setsEarlyMin(sEarlyMin);
						report.settEarlyMin(tEarlyMin);
						report.setfCheckintime(fCheckin);
						report.setsCheckintime(sCheckin);
						report.settCheckintime(tCheckin);
						report.setfCheckouttime(fCheckout);
						report.setsCheckouttime(sCheckout);
						report.settCheckouttime(tCheckout);
						report.setSiteid(userid.substring(0, 6));
						reportDAO.insert(report);
					}
					//System.out.println("shouldHours=" + shouldHours);
				}
				calendar.add(Calendar.DATE, 1);
				curDate = calendar.getTime();
			}	
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
}
